<template>
  <BaseCharts ref="baseChartsRef" :options="options" autoRander :autoNumber="autoNumber"></BaseCharts>
</template>

<script setup>
import BaseCharts from "@/components/echarts/vpt-base-chart/index.vue";
import { fontSize } from "@/utils/rem/rem.js";
import { watch, ref, nextTick, computed } from "vue";
import { getChartTootipFormatter } from "@/utils/formatter.js";
import { useEchart } from "@/hooks/useEchart.js";
import { addThousandsSeparator } from "@/utils/formatter.js";

const props = defineProps({
  chartType: { type: String, default: "init" },
  // 宽度
  width: { type: Number, default: 280 },
  // 高度
  height: { type: Number, default: 280 },
  chartData: { type: Array, default: () => [] },
  // 图形位置
  center: { type: Array, default: () => ["50%", "80%"] },
  // 图形
  radius: { type: Array, default: () => ["45%", "50%"] },
  // 图例配置项
  legendProps: { type: Object, default: () => ({}) },
  // 中心内容配置项
  titleProps: { type: Object, default: () => ({}) },
  // 饼颜色
  color: { type: Array, default: () => [] },
  // 循环渲染
  autoRander: { type: Boolean, default: false },
  // 循环渲染间隔 单位S
  autoNumber: { type: Number, default: 60 },
  // 图例文本字号
  legendFontSize: { type: Number, default: 12 },
  // 图例系列名内边距
  legendNamePadding: {
    type: Array,
    default: () => [0, fontSize(40), 0, fontSize(20)],
  },
  // 标题字号
  titleFontSize: { type: Number, default: 14 },
  // 总数字号
  totalFontSize: { type: Number, default: 22 },
  titleText: { type: String, default: "总数" },
});

const options = ref({});
// 使用hooks
useEchart(getOptions);

const baseChartsRef = ref(null);

watch(
  () => ({ chartData: props.chartData, chartType: props.chartType }),
  () => {
    nextTick(async () => {
      if (props.chartType == "update") {
        updateSeries();
      } else {
        getOptions();
      }
    });
  },
  { deep: true }
);
const totalNum = computed(() => {
  return props.chartData.reduce((pre, cur) => cur.total_num, 0);
});

// 获取对应字段最大宽度
const getDataWidth = () => {
  let labelWidth = 0;
  let valueWidth = 0;
  let percentWidth = 0;

  props.chartData.forEach((v) => {
    const { width: width1 } = getTextWidth(
      v.name,
      `${fontSize(props.legendFontSize)}px PingFangSC-Medium`
    );
    const { width: width2 } = getTextWidth(
      v.value,
      `${fontSize(props.legendFontSize)}px PingFangSC-Medium`
    );
    const { width: width3 } = getTextWidth(
      v.percent,
      `${fontSize(props.legendFontSize)}px PingFangSC-Medium`
    );
    if (width1 >= labelWidth) {
      labelWidth = width1;
    }
    if (width2 >= valueWidth) {
      valueWidth = width2;
    }
    if (width3 >= percentWidth) {
      percentWidth = width3;
    }
  });

  return {
    labelWidth,
    valueWidth,
    percentWidth,
  };
};

// 获取字段宽度
const getTextWidth = (text, font) => {
  const canvas = document.createElement("canvas");
  const ctx = canvas.getContext("2d");
  ctx.font = font;
  const metrics = ctx.measureText(text);
  return {
    width: metrics.width,
  };
};

function getOptions() {
  const { labelWidth, valueWidth, percentWidth } = getDataWidth();
  options.value = {
    animation: false,
    width: fontSize(props.width),
    height: fontSize(props.height),
    title: {
      text:
        "{name|" +
        props.titleText +
        "}\n{val|" +
        addThousandsSeparator(totalNum.value) +
        "}",
      left: "center",
      top: "center",
      textAlign: "center",
      textStyle: {
        color: "#fff",
        fontWeight: 400,
        height: fontSize(16),
        fontFamily: "HarmonyOS_SansSC_Medium",
        rich: {
          name: {
            fontSize: fontSize(props.titleFontSize),
            fontWeight: "400",
            color: "#1D2129",
            fontFamily: "HarmonyOS_SansSC_Medium",
            textAlign: "center",
            lineHeight:fontSize(26)
            // padding: [23, -20],
          },
          val: {
            fontSize: fontSize(props.totalFontSize),
            fontWeight: 400,
            fontFamily: "HarmonyOS_SansSC_Medium",
            color: "#1D2129",
            textAlign: "center",
            // padding: [-30, -20],
          },
        },
      },
      ...props.titleProps,
    },
    tooltip: {
      trigger: "item",
      textStyle: {
        fontFamily: "HarmonyOS_SansSC_Medium",
      },
      borderColor: "#4895e899",
      extraCssText: "background: #fff", //渐变颜色
      formatter: (item) => {
        return getChartTootipFormatter(
          [item],
          { itemKey: "name", valueKey: "value" },
          false
        );
      },
    },
    legend: {
      selectedMode: false,
      top: "30%",
      left: "45%",
      orient: "vertical",
      itemWidth: fontSize(12),
      itemHeight: fontSize(12),
      formatter: (name) => {
        const findObj = props.chartData.find((v) => v.name === name) || {};

        return `{name|${name}} {percent|${findObj.percent
          }} {value|${addThousandsSeparator(findObj.value)}}`;
      },
      textStyle: {
        // fontSize: 14,
        rich: {
          name: {
            fontSize: fontSize(props.legendFontSize),
            color: "#1D2129",
            width: labelWidth,
            fontFamily: "HarmonyOS_SansSC_Medium",
            padding: props.legendNamePadding,
          },
          value: {
            fontSize: fontSize(props.legendFontSize),
            color: "#1D2129",
            width: valueWidth,
            align: "left",
            fontFamily: "HarmonyOS_SansSC_Medium",
          },
          percent: {
            fontSize: fontSize(props.legendFontSize),
            color: "#1D2129",
            width: fontSize(50),
            align: "left",
            fontFamily: "HarmonyOS_SansSC_Medium",
            paddingRight: fontSize(20),
          },
          other: {
            fontSize: 14,

            fontFamily: "HarmonyOS_SansSC_Medium",
          },
        },
      },
      itemGap: fontSize(30),
      icon: "rect",
      ...props.legendProps,
    },
    grid: {
      left: fontSize(100),
      right: 0,
      bottom: 0,
      top: 100,
    },
    series: [
      {
        type: "pie",
        radius: props.radius,
        center: ["50%", "40%"],
        avoidLabelOverlap: false,
        label: {
          show: false,
          position: "center",
        },
        emphasis: {
          label: {
            show: false,
          },
        },
        labelLine: {
          show: false,
        },
        data: props.chartData,
        color: props.color,
      },
    ],
  };
}

function getEchartsInstance() {
  return new Promise((resolve) => {
    baseChartsRef.value.commonFunc((instance) => resolve(instance));
  });
}

// 更新图表
async function updateSeries() {
  try {
    const chartInstance = await getEchartsInstance();
    if (chartInstance) {
      const newChartOption = chartInstance.getOption();
      // 遍历 series 更新 data

      (newChartOption.title[0].text =
        "{name|" +
        props.titleText +
        "}\n{val|" +
        addThousandsSeparator(totalNum.value) +
        "}"),
        (newChartOption.series[0].data = props.chartData);
      (newChartOption.legend.formatter = (name) => {
        const findObj = props.chartData.find((v) => v.name === name) || {};

        return `{name|${name}} {percent|${findObj.percent
          }} {value|${addThousandsSeparator(findObj.value)}}`;
      }),
        // 更新 series 部分
        chartInstance.setOption(newChartOption, false);
    }
  } catch (error) {
    // console.error("Failed to update chart:", error);
  }
}

defineExpose({
  reloadEchart: () => {
    baseChartsRef.value.reloadEchart();
  },
});
</script>
